package org.dromara.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.web.domain.SysJob;
import org.dromara.web.mapper.JobMapper;
import org.dromara.web.service.jobStatusService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 定时任务StatusService业务层处理
 *
 * @author Zou
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class jobStatusServiceImpl implements jobStatusService {


    private final JobMapper baseMapper;

    // 修改成员变量定义
    private Map<String, String> previousServices = new HashMap<>(); // key: serviceName_serviceMethod, value: methodName

    private Map<String, Integer> previousMethodStatus = new HashMap<>(); // 新增成员变量记录methodName对应的状态

    private final ApplicationContext applicationContext;  // 注入Spring上下文来获取动态的Service

    /**
     * 更新指定methodName的状态
     *
     * @param methodName
     * @param newStatus
     */
    @Override
    public void updateJobStatus(String methodName, int newStatus) {
        LambdaQueryWrapper<SysJob> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysJob::getMethodName, methodName);
        SysJob jobToUpdate = baseMapper.selectOne(lqw);

        if (jobToUpdate != null) {
            jobToUpdate.setStatus(String.valueOf(newStatus));
            baseMapper.updateById(jobToUpdate);
            log.info("更新methodName[{}]的状态为{}", methodName, newStatus);
        }
    }

    /**
     * 更新当前方法的状态，并记录前一个方法的状态
     *
     * @param methodName
     * @param serviceName
     * @param serviceMethod
     * @return
     */
    @Override
    public SysJob updateCurrentMethodStatus(String methodName, String serviceName, String serviceMethod) {
        String key = serviceName + "_" + serviceMethod;
        resetPreviousMethodStatus(methodName, serviceName, serviceMethod);

        // 检查是否已有完全相同的三个参数（serviceName/serviceMethod/methodName）
        if (previousServices.containsKey(key) && previousServices.get(key).equals(methodName)) {
            log.info("相同的定时任务已存在，状态不递增");
            return null;
        }

        // 执行状态更新操作
        LambdaQueryWrapper<SysJob> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysJob::getMethodName, methodName).select(SysJob::getJobId, SysJob::getCronExpression, SysJob::getStatus);
        SysJob job = baseMapper.selectOne(lqw);

        if (job != null) {
            try {
                int currentStatus = Integer.parseInt(job.getStatus());
                job.setStatus(String.valueOf(currentStatus + 1));
                baseMapper.updateById(job);
                // 更新记录
                previousServices.put(key, methodName);
                previousMethodStatus.put(methodName, currentStatus + 1);
                log.info("已设置 methodName[{}] 状态为 {}", methodName, job.getStatus());
            } catch (NumberFormatException e) {
                log.error("状态字段格式错误: {}", job.getStatus());
            }
        }
        return job;
    }

    /**
     * 重置前一个方法的状态
     *
     * @param methodName
     * @param serviceName
     * @param serviceMethod
     */
    @Override
    public void resetPreviousMethodStatus(String methodName, String serviceName, String serviceMethod) {
        String key = serviceName + "_" + serviceMethod;
        if (previousServices.containsKey(key)) {
            String previousMethod = previousServices.get(key);
            // 仅当 methodName 不同时，重置旧状态
            if (!previousMethod.equals(methodName)) {
                Integer previousStatus = previousMethodStatus.get(previousMethod);
                if (previousStatus != null && previousStatus > 0) {
                    previousMethodStatus.put(previousMethod, previousStatus - 1);
                    updateJobStatus(previousMethod, previousStatus - 1);
                    log.info("已重置旧 methodName[{}] 状态为 {}", previousMethod, previousStatus - 1);
                }
                previousServices.remove(key); // 移除旧记录
            }
        }
    }

    /**
     * 重置所有方法的状态
     * 注意：这是一个全局操作，会影响所有方法的状态
     */
    @Override
    @PreDestroy
    public void resetAllMethodStatus() {
        // 1. 清空本地缓存
        previousServices.clear();
        previousMethodStatus.clear();
        log.info("已清空本地状态缓存");

        // 2. 重置数据库状态为0
        try {
            int affectedRows = baseMapper.resetAllStatusToZero();
            log.info("已重置数据库所有任务的status为0，影响行数：{}", affectedRows);
        } catch (Exception e) {
            log.error("重置数据库状态失败", e);
            throw new RuntimeException("全局状态重置失败，请检查数据库连接");
        }

    }

    /**
     * 状态减1
     *
     * @param methodName
     */
    @Override
    public void decrementStatus(String methodName) {
        if (StringUtils.isBlank(methodName)) return;

        LambdaQueryWrapper<SysJob> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysJob::getMethodName, methodName);
        SysJob job = baseMapper.selectOne(lqw);

        if (job != null) {
            try {
                int currentStatus = Integer.parseInt(job.getStatus());
                if (currentStatus > 0) {
                    job.setStatus(String.valueOf(currentStatus - 1));
                    baseMapper.updateById(job);
                    log.info("methodName[{}] 状态已减1，当前状态: {}", methodName, job.getStatus());
                }
            } catch (NumberFormatException e) {
                log.error("状态字段格式错误: {}", job.getStatus());
            }
        }
    }

    @Override
    public String getCurrentMethodName(String serviceName, String serviceMethod) {
        String key = serviceName + "_" + serviceMethod;
        return previousServices.getOrDefault(key, null);
    }

    @Override
    public void removeMethodNameFromCache(String serviceName, String serviceMethod) {
        String key = serviceName + "_" + serviceMethod;
        String methodName = previousServices.get(key);
        if (methodName != null) {
            // 清除 previousServices 和 previousMethodStatus
            previousServices.remove(key);
            previousMethodStatus.remove(methodName);
            log.info("已清除缓存记录: serviceName={}, serviceMethod={}", serviceName, serviceMethod);
        }
    }


}
